﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SchoolDAL;

namespace StudentEFConsoleApp
{
   public class EntityObjectDemo
    {
        public static void AddDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                Student student = ctx.CreateObject<Student>();

                Standard std = ctx.CreateObject<Standard>();
                std.StandardName = "EntityObjectDemo Standard1";

                student.StudentName = "EntityObjectDemo Student1";
                student.Standard = std;

                ctx.Students.AddObject(student);
                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo AddDemo successfull");
            }
        }

        public static void AddOneToOneDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                Student student = ctx.CreateObject<Student>();
                student.StudentName = "EntityObjectDemo Student2";

                Standard std = ctx.CreateObject<Standard>();
                std.StandardName = "EntityObjectDemo Standard2";
                
                student.Standard = std;

                StudentAddress sAddress = ctx.CreateObject<StudentAddress>();

                sAddress.Address1 = "Address1";
                sAddress.Address2 = "Address2";
                sAddress.City = "City1";
                sAddress.State = "State1";

                student.StudentAddress = sAddress;

                ctx.Students.AddObject(student);
                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo AddOneToOneDemo Successfull");
            }
        }

        //Adding many teachers for one standard
        public static void AddOneToManyDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                Standard std = ctx.CreateObject<Standard>();

                std.StandardName = "EntityObjectDemo standard3";
                std.Description = "Demo std";

                Teacher teacher1 = ctx.CreateObject<Teacher>();
                teacher1.TeacherName = "EntityObjectDemo Teacher1";

                Teacher teacher2 = ctx.CreateObject<Teacher>();
                teacher2.TeacherName = "EntityObjectDemo Teacher2";

                Teacher teacher3 = ctx.CreateObject<Teacher>();
                teacher3.TeacherName = "EntityObjectDemo Teacher3";


                //Adding many teachers for one standard
                std.Teachers.Add(teacher1);
                std.Teachers.Add(teacher2);
                std.Teachers.Add(teacher3);


                ctx.Standards.AddObject(std);
                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo AddOneToManyDemo Successfull");
            }
        }


        public static void AddManyToManyDemo()
        {

            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {

                Student student = ctx.CreateObject<Student>();

                Standard std = ctx.CreateObject<Standard>();
                std.StandardName = "EntityObjectDemo Standard3";

                student.StudentName = "EntityObjectDemo Student3";
                student.Standard = std;

                Course course1 = ctx.CreateObject<Course>();
                course1.CourseName = "EntityObjectDemo Course1";
                course1.Location = "City1";

                Course course2 = ctx.CreateObject<Course>();
                course2.CourseName = "EntityObjectDemo Course2";
                course2.Location = "City2";

                Course course3 = ctx.CreateObject<Course>();
                course3.CourseName = "EntityObjectDemo Course3";
                course3.Location = "City1";

                Teacher teacher1 = ctx.CreateObject<Teacher>();
                teacher1.TeacherName = "EntityObjectDemo teacher1";
                teacher1.Standard = std;

                //assign teacher1 for each courses
                course1.Teacher = teacher1;
                course2.Teacher = teacher1;
                course3.Teacher = teacher1;

                //Add courses to student
                student.Courses.Add(course1);
                student.Courses.Add(course2);
                student.Courses.Add(course3);

                ctx.Students.AddObject(student);
                ctx.SaveChanges();
            }

            Console.WriteLine("EntityObjectDemo AddManyToManyDemo Successfull");

        }


        public static void UpdateDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {

                var stud = (from s in ctx.Students
                            where s.StudentName == "EntityObjectDemo Student1"
                            select s).FirstOrDefault();

                stud.StudentName = "Updated EntityObjectDemo Student1";

                int num = ctx.SaveChanges();
            }

            Console.WriteLine("EntityObjectDemo UpdateDemo successfull");

        }

        public static void UpdateOneToOneDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                Student student = (from s in ctx.Students
                                   where s.StudentName == "EntityObjectDemo Student2"
                                   select s).FirstOrDefault<Student>();



                student.StudentName = "Updated EntityObjectDemo Student2"; 

                StudentAddress sAddress = student.StudentAddress;

                sAddress.Address1 = "Updated EntityObjectDemo Address2";
                sAddress.Address2 = "Updated EntityObjectDemo Address2";
                sAddress.City = "Updated EntityObjectDemo City2";
                sAddress.State = "Updated EntityObjectDemo State2";

                student.StudentAddress = sAddress;

                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo UpdateOneToOneDemo Successfull");
            }
        }

       //Updates Standard name and add one more teacher and removing one existing teacher from that standard 
       //thus teachers of that standard will be updated.
        public static void UpdateOneToManyDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                //fetching existing standard from the db
                Standard std = (from s in ctx.Standards.Include("Teachers")
                                where s.StandardName == "EntityObjectDemo standard3"
                                select s).FirstOrDefault<Standard>();

                std.StandardName = "Updated EntityObjectDemo standard3";
                std.Description = "Updated";

                //getting first teacher to be removed
                //Teacher tchr = std.Teachers.FirstOrDefault<Teacher>();
                ////removing teachers 
                //if (tchr != null)
                //    ctx.Teachers.DeleteObject(tchr);

                //Do not use std.Teachers.Remove(tchr). It will give exception. 
                //This statement doesn't remove teacher from teachers collection but it trying to remove relationship.
                //std.Teachers.Remove(tchr);

                 Teacher newTeacher = ctx.CreateObject<Teacher>();
                 newTeacher.TeacherName = "EntityObjectDemo new Teacher";

                std.Teachers.Add(newTeacher);

                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo UpdateOneToManyDemo Successfull");
            }
        }

       //removes one course from student's course lists
        public static void UpdateManyToManyDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {

                Student student = (from s in ctx.Students.Include("Courses")
                                   where s.StudentName == "EntityObjectDemo Student3"
                                   select s).FirstOrDefault<Student>();


                student.StudentName = "Updated EntityObjectDemo Student3";

                Course cours = student.Courses.FirstOrDefault<Course>();

                //removing course from student
                student.Courses.Remove(cours);

                ctx.SaveChanges();
            }

            Console.WriteLine("EntityObjectDemo UpdateManyToManyDemo Successfull");
        }

        public static void DeleteDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {


                var stud = (from s in ctx.Students
                            where s.StudentName == "Updated EntityObjectDemo Student1"
                            select s).FirstOrDefault();

                ctx.Students.DeleteObject(stud);

                int num = ctx.SaveChanges();
            }
            Console.WriteLine("EntityObjectDemo DeleteDemo successfull");
        }

        public static void DeleteOneToOneDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                Student student = (from s in ctx.Students.Include("StudentAddress")
                                   where s.StudentName == "Updated EntityObjectDemo Student2"
                                   select s).FirstOrDefault<Student>();



                StudentAddress sAddress = student.StudentAddress;

                ctx.StudentAddresses.DeleteObject(sAddress);

                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo DeleteOneToOneDemo Successfull");
            }
        }

        public static void DeleteOneToManyDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {
                //fetching existing standard from the db
                Standard std = (from s in ctx.Standards
                                where s.StandardName == "Updated EntityObjectDemo standard3"
                                select s).FirstOrDefault<Standard>();

               
                //getting first teacher to be removed
                Teacher tchr = std.Teachers.FirstOrDefault<Teacher>();
                //removing teachers 
                ctx.Teachers.DeleteObject(tchr);

                //Do not use std.Teachers.Remove(tchr). It will give exception. 
                //This statement doesn't remove teacher from teachers collection but it trying to remove relationship.
                //std.Teachers.Remove(tchr);

                ctx.SaveChanges();

                Console.WriteLine("EntityObjectDemo DeleteOneToManyDemo Successfull");
            }
        }

        //removes one course from student's course lists: same as update
        public static void DeleteManyToManyDemo()
        {
            using (SchoolDBEntities ctx = new SchoolDBEntities())
            {

                Student student = (from s in ctx.Students
                                   where s.StudentName == "Updated EntityObjectDemo Student3"
                                   select s).FirstOrDefault<Student>();


                Course cours = student.Courses.FirstOrDefault<Course>();

                //removing course from student
                student.Courses.Remove(cours);

                ctx.SaveChanges();
            }

            Console.WriteLine("EntityObjectDemo DeleteManyToManyDemo Successfull");
        }
    }
}
